package com.mind.adjust.service.impl;

import com.mind.adjust.domain.vo.*;
import com.mind.adjust.domain.vo.rulepassdetail.RulePassDetailListVo;
import com.mind.adjust.mapper.*;
import com.mind.cache.service.CacheService;
import com.mind.common.constant.RuleConstants;
import com.mind.common.exception.ServiceException;
import com.mind.common.utils.StringUtils;
import com.mind.customer.domain.vo.RulePassRateListVo;
import com.mind.customer.mapper.AjCheckResultMapper;
import com.mind.customer.mapper.AjRuleMapper;
import com.mind.customer.mapper.AjTicketTaskMapper;
import com.mind.customer.mapper.AjTicketTypeMapper;
import com.mind.customer.utils.CateUtils;
import com.mind.system.domain.*;
import com.mind.adjust.service.AjTicketTaskService;
import com.mind.system.domain.vo.CateResult;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;


import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 单据任务(AjTicketTask)表服务实现类
 *
 * @author makejava
 * @since 2024-07-17 22:20:04
 */
@Service("ticketTaskService")
public class AjTicketTaskServiceImpl implements AjTicketTaskService {
    @Autowired
    private AjTicketTaskMapper ticketTaskMapper;
    @Resource
    private AjTicketTypeMapper ticketTypeMapper;

    @Resource
    private AjCheckResultMapper checkResultMapper;

    @Resource
    private CacheService cacheService;

    @Resource
    private AjRuleMapper ruleMapper;

    @Resource
    private CateUtils cateUtils;

    @Resource
    private AjAttachCateBusinessMapper attachCateBusinessMapper;

    @Resource
    private AjRuleDetailMapper ruleDetailMapper;

    @Resource
    private AjAttachCateRulesetMapper attachCateRulesetMapper;

    /**
     * 查询单据任务信息集合
     *
     * @param ticketTask 单据任务信息
     * @return 单据任务信息集合
     */
    @Override
    public List<AjTicketTask> selectTicketTaskList(AjTicketTask ticketTask) {
        List<AjTicketTask> ticketTasks = null;
        if (ticketTask != null && ticketTask.getIsDisplayOnlyHigherVersion() != null && ticketTask.getIsDisplayOnlyHigherVersion()) {
            ticketTasks = ticketTaskMapper.selectTicketOnlyHignestVersion(ticketTask);
        } else {
            ticketTasks = ticketTaskMapper.selectTicketTaskList(ticketTask);
        }
        Map<String, AjTicketType> ticketTypeMap = new HashMap<>();
        Map<String, String> mainCate = new HashMap<>();
        if (cacheService.hasKey("mainCateCache")) {
            mainCate = cacheService.getCacheObject("mainCateCache");
        }
        Map<String, String> subCate = new HashMap<>();
        if (cacheService.hasKey("subCateCache")) {
            subCate = cacheService.getCacheObject("subCateCache");
        }
        for (AjTicketTask task : ticketTasks) {
            if (!ticketTypeMap.containsKey(task.getTicketType())) {
                List<AjTicketType> ajTicketTypes = ticketTypeMapper.selectTicketTypeList(new AjTicketType() {{
                    setCode(task.getTicketType());
                }});
                if (!CollectionUtils.isEmpty(ajTicketTypes)) {
                    ticketTypeMap.put(task.getTicketType(), ajTicketTypes.get(0));
                }
            }
            AjTicketType ajTicketType = ticketTypeMap.get(task.getTicketType());
            if (StringUtils.isNotNull(ajTicketType)) {
                task.setTicketType(ajTicketType.getName());
                task.setOriginalField(ajTicketType.getModuleName());
            }
            if (StringUtils.isNotEmpty(task.getBusinessCate()) && !subCate.isEmpty()) {
                Map<String, String> finalSubCate = subCate;
                task.setBusinessCate(Arrays.stream(task.getBusinessCate().split(",")).map(item -> finalSubCate.getOrDefault(item, item)).collect(Collectors.joining(",")));
            }
            if (StringUtils.isNotEmpty(task.getBusinessMainCate()) && !mainCate.isEmpty()) {
                task.setBusinessMainCate(mainCate.getOrDefault(task.getBusinessMainCate(), task.getBusinessMainCate()));
            }
        }
        return ticketTasks;
    }

    /**
     * 通过单据任务ID查询单据任务信息
     *
     * @param ticketTaskId 单据任务ID
     * @return 角色对象信息
     */
    @Override
    public AjTicketTask selectTicketTaskById(Long ticketTaskId) {
        return ticketTaskMapper.selectTicketTaskById(ticketTaskId);
    }

    /**
     * 删除单据任务信息
     *
     * @param ticketTaskId 单据任务ID
     * @return 结果
     */
    @Override
    public int deleteTicketTaskById(Long ticketTaskId) {
        return ticketTaskMapper.deleteTicketTaskById(ticketTaskId);
    }

    /**
     * 批量删除单据任务信息
     *
     * @param ticketTaskIds 需要删除的单据任务ID
     * @return 结果
     */
    @Override
    public int deleteTicketTaskByIds(Long[] ticketTaskIds) {
        return ticketTaskMapper.deleteTicketTaskByIds(ticketTaskIds);
    }

    /**
     * 新增保存单据任务信息
     *
     * @param ticketTask 单据任务信息
     * @return 结果
     */
    @Override
    public int insertTicketTask(AjTicketTask ticketTask) {
        return ticketTaskMapper.insertTicketTask(ticketTask);
    }

    /**
     * 修改保存单据任务信息
     *
     * @param ticketTask 单据任务信息
     * @return 结果
     */
    @Override
    public int updateTicketTask(AjTicketTask ticketTask) {
        return ticketTaskMapper.updateTicketTask(ticketTask);
    }

    /**
     * 批量插入
     *
     * @param ticketTaskList 附件类型信息
     * @return 结果
     */
    @Override
    public int batchInsert(List<AjTicketTask> ticketTaskList) {
        int size = 0;
//        for(AjTicketTask ticketTask: ticketTaskList) {
//            if (ticketTaskMapper.selectTicketTaskByName(ticketTask.getName()) == null){
//                ticketTaskMapper.insertTicketTask(ticketTask);
//                size ++;
//            }
//        }
        return size;
    }

    /**
     * @param ticketId
     * @return
     */
    @Override
    public AjTicketTask selectTicketTaskByTicketId(String ticketId) {
        return ticketTaskMapper.selectTicketTaskByTicketId(ticketId);
    }

    /**
     * @param ticketId
     * @return
     */
    @Override
    public AjTicketTask selectLastVersionTask(String ticketId) {
        return ticketTaskMapper.selectLastVersionTask(ticketId);
    }

    @Override
    public int check(AjTicketTask task) {
        if (task.getId() == null) {
            throw new ServiceException("Id 不能为空。");
        }
        AjTicketTask checkTask = ticketTaskMapper.selectTicketTaskById(task.getId().longValue());
        AjTicketTask lastTask = ticketTaskMapper.selectLastVersionTask(checkTask.getTicketId());
        checkTask.setVersion(lastTask.getVersion() + 1);
        checkTask.setId(null);
        checkTask.setStatus(1);
        // 只触发查验
        checkTask.setTriggerType(1);
        return ticketTaskMapper.insertTicketTask(checkTask);
    }

    @Override
    public List<AjTicketTask> selectByStatusList(String ticketId, List<Integer> statusList) {
        return ticketTaskMapper.selectByStatusList(ticketId, statusList);
    }

    @Override
    public List<TicketDetailListVo> smartCheckDetail(AjTicketTask task) {
        List<TicketDetailListVo> ticketTaskDetailVos = new ArrayList<>();
        List<AjTicketTask> ticketTasks = ticketTaskMapper.selectTicketOnlyHignestVersion(task);
        Map<String, String> mainCate = new HashMap<>();
        if (cacheService.hasKey("mainCateCache")) {
            mainCate = cacheService.getCacheObject("mainCateCache");
        }
        Map<String, String> subCate = new HashMap<>();
        if (cacheService.hasKey("subCateCache")) {
            subCate = cacheService.getCacheObject("subCateCache");
        }
        Map<Integer, AjRule> ruleMap = new HashMap<>();
        for (AjTicketTask ticketTask : ticketTasks) {
            List<AjCheckResult> resultList = checkResultMapper.selectCheckResultList(new AjCheckResult() {{
                setTicketId(ticketTask.getTicketId());
                setVersion(ticketTask.getVersion());
            }});


            for (AjCheckResult result : resultList) {
                if (!ruleMap.containsKey(result.getRuleId())) {
                    List<AjRule> rules = ruleMapper.selectByParams2(null, null, result.getRuleId(), null, null);
                    if (!CollectionUtils.isEmpty(rules)) {
                        ruleMap.put(result.getRuleId(), rules.get(0));
                    }
                }
                AjRule rule = ruleMap.get(result.getRuleId());
                TicketDetailListVo detailVo = new TicketDetailListVo();
                detailVo.setVoucherType(cateUtils.getTicketTypeName(ticketTask.getTicketType()));
                detailVo.setApplyDate(ticketTask.getApplyDate());
                detailVo.setVersion(ticketTask.getVersion());
                detailVo.setAuditTime(ticketTask.getCompleteTime());
                detailVo.setVoucherNumber(ticketTask.getTicketId());
                detailVo.setAuditCount(ticketTask.getVersion());
                detailVo.setApplicant(ticketTask.getApplyPerson());
                detailVo.setDepartment(ticketTask.getApplyDept());
                detailVo.setCompany(ticketTask.getApplyComp());
                detailVo.setManualProcessor(ticketTask.getHandleNickname());
                detailVo.setAuditStatus(ticketTask.getStatus());
                detailVo.setManualProcessing(ticketTask.getHandleResult());
                detailVo.setRuleDetailId(result.getRuleDetailId());
//                detailVo.setProcessingOpinion(ticketTask.getRemark());
//                detailVo.setBusinessCategoryMinor(ticketTask.getBusinessCate());
                if (StringUtils.isNotEmpty(ticketTask.getBusinessCate()) && !subCate.isEmpty()) {
                    Map<String, String> finalSubCate = subCate;
                    detailVo.setBusinessCategoryMinor(Arrays.stream(ticketTask.getBusinessCate().split(",")).map(item -> finalSubCate.getOrDefault(item, item)).collect(Collectors.joining(",")));
                }
                if (StringUtils.isNotEmpty(ticketTask.getBusinessMainCate()) && !mainCate.isEmpty()) {
                    detailVo.setBusinessCategoryMajor(mainCate.getOrDefault(ticketTask.getBusinessMainCate(), ticketTask.getBusinessMainCate()));
                }
                detailVo.setBusinessCate(ticketTask.getBusinessCate());
                detailVo.setProcessingOpinion(result.getRealHandlerType());
                detailVo.setRemarks(result.getRemark());
                // todo 业务大类
                detailVo.setRuleVersion(result.getRuleDesc());
                detailVo.setRuleName(result.getRuleName());
                if (rule != null && rule.getRuleDetail() != null) {
                    detailVo.setRuleType(rule.getRuleDetail().getAttachCate());
                    detailVo.setRuleCode(rule.getRuleDetail().getCode());
                    detailVo.setRuleSet(rule.getRuleDetail().getRuleGroup());
                }
                detailVo.setResultStatus(result.getStatus());
                if(rule != null && rule.getStatus() != null) {
                    detailVo.setRuleStatus(Integer.valueOf(rule.getStatus()));
                }
//                detailVo.setCheckResult(result.getCheckResult());
                ticketTaskDetailVos.add(detailVo);
            }
        }
        if (StringUtils.isNotEmpty(task.getRuleVersion())) {
            ticketTaskDetailVos = ticketTaskDetailVos.stream().filter(item -> item.getRuleVersion().contains(task.getRuleVersion())).collect(Collectors.toList());
        }

        if (StringUtils.isNotEmpty(task.getRuleType())) {
            ticketTaskDetailVos = ticketTaskDetailVos.stream().filter(item -> item.getRuleType().contains(task.getRuleType())).collect(Collectors.toList());
        }

        if (StringUtils.isNotEmpty(task.getRuleset())) {
            ticketTaskDetailVos = ticketTaskDetailVos.stream().filter(item -> item.getRuleSet().contains(task.getRuleset())).collect(Collectors.toList());
        }

        if (StringUtils.isNotEmpty(task.getRuleDetailName())) {
            ticketTaskDetailVos = ticketTaskDetailVos.stream().filter(item -> item.getRuleName().contains(task.getRuleDetailName())).collect(Collectors.toList());
        }

        return ticketTaskDetailVos;
    }

    @Override
    public List<RulePassDetailListVo> smartCheckPassList(AjTicketTask task) {
        List<AjTicketTask> ticketTasks = ticketTaskMapper.selectTicketOnlyHignestVersion(task);
        List<RulePassDetailListVo> detailListVos = new ArrayList<>();
        for (AjTicketTask ticketTask : ticketTasks) {
            // 包含未上线的小类, 不参与统计
            CateResult cateResult = cateUtils.existsCate(RuleConstants.OFFLINE_CATE, ticketTask.getBusinessCate(), ticketTask.getTicketType());
            if (cateResult.getExists()) {
                continue;
            }
            // 混报特殊小类， 不参与统计
            CateResult specialResult = cateUtils.existsCate(RuleConstants.MULTIPLE_CATE, ticketTask.getBusinessCate(), ticketTask.getTicketType());
            if (specialResult.getExists()) {
                continue;
            }
            RulePassDetailListVo detailVo = new RulePassDetailListVo();
            BeanUtils.copyProperties(ticketTask, detailVo);
            detailVo.setBusinessMainCate(cateUtils.getMainCate(detailVo.getBusinessMainCate()));
            detailVo.setBusinessCate(cateUtils.getSmallCate(detailVo.getBusinessCate()));
            detailVo.setTicketType(cateUtils.getTicketTypeName(ticketTask.getTicketType()));
            detailVo.setFailCount(detailVo.getTotalCount()-detailVo.getPassCount());
            detailListVos.add(detailVo);
        }
        return detailListVos;
    }

    @Override
    public List<RulePassRateListVo> smartCheckPassRate(AjTicketTask task) {
        List<RulePassRateListVo> detailListVos = checkResultMapper.selectRulePassRate(task);
        List<AjRuleDetail> ajRuleDetailList = ruleDetailMapper.selectRuleDetailList(new AjRuleDetail());
        Map<Integer, AjRuleDetail> ajRuleDetailMap = ajRuleDetailList.stream().collect(Collectors.toMap(AjRuleDetail::getId, ruleDetail -> ruleDetail));
        detailListVos.forEach(vo -> {
            AjRuleDetail detail = ajRuleDetailMap.get(vo.getRuleDetailId());
            if (detail != null) {
                vo.setRuleDetailName(detail.getName());
                vo.setRuleSet(detail.getRuleGroup());
                vo.setRuleType(detail.getAttachCate());
            }
            if (vo.getCount() > 0) {
                if(vo.getPassCount() == null){
                    vo.setPassCount(0);
                }
                vo.setRulePassRate(Math.round(vo.getPassCount() * 1.0 / vo.getCount() * 10000) / 10000.0);
            } else {
                vo.setRulePassRate(0.0);
            }
        });
        if (StringUtils.isNotEmpty(task.getRuleType())) {
            detailListVos = detailListVos.stream().filter(item -> item.getRuleType().contains(task.getRuleType())).collect(Collectors.toList());
        }

        if (StringUtils.isNotEmpty(task.getRuleset())) {
            detailListVos = detailListVos.stream().filter(item -> item.getRuleSet().contains(task.getRuleset())).collect(Collectors.toList());
        }

        if (StringUtils.isNotEmpty(task.getRuleDetailName())) {
            detailListVos = detailListVos.stream().filter(item -> item.getRuleDetailName().contains(task.getRuleDetailName())).collect(Collectors.toList());
        }
        return detailListVos;
    }

//    @Override
//    public List<RulePassRateListVo> smartCheckPassRate(AjTicketTask task) {
//        List<TicketDetailListVo> ticketTaskDetailVos = smartCheckDetail(task);
//        Map<Long, RulePassRateListVo> rulePassDetailListVoMap = new HashMap<>();
//        for (TicketDetailListVo detailVo : ticketTaskDetailVos) {
//            if(detailVo.getResultStatus() == null || detailVo.getResultStatus() == 4){
//                continue;
//            }
//            // 包含未上线的小类, 不参与统计
//            CateResult cateResult = cateUtils.existsCate(RuleConstants.OFFLINE_CATE, detailVo.getBusinessCate());
//            if (cateResult.getExists()) {
//                continue;
//            }
//            // 混报特殊小类， 不参与统计
//            CateResult specialResult = cateUtils.existsCate(RuleConstants.MULTIPLE_CATE, detailVo.getBusinessCate());
//            if (specialResult.getExists()) {
//                continue;
//            }
//
//            if (!rulePassDetailListVoMap.containsKey(detailVo.getRuleDetailId())) {
//                RulePassRateListVo rulePassDetailListVo = new RulePassRateListVo();
//                rulePassDetailListVo.setRuleSet(detailVo.getRuleSet());
//                rulePassDetailListVo.setRuleType(detailVo.getRuleType());
//                rulePassDetailListVo.setRuleDetailName(detailVo.getRuleName());
//                if (detailVo.getResultStatus().equals(1)) {
//                    rulePassDetailListVo.setPassCount(1);
//                }
//                if (com.alibaba.nacos.common.utils.CollectionUtils.contains(Arrays.asList(1, 2, 3), detailVo.getResultStatus())) {
//                    rulePassDetailListVo.setCount(1);
//                }
//                rulePassDetailListVoMap.put(detailVo.getRuleDetailId(), rulePassDetailListVo);
//            } else {
//                RulePassRateListVo rulePassDetailListVo = rulePassDetailListVoMap.get(detailVo.getRuleDetailId());
//                if (detailVo.getResultStatus().equals(1)) {
//                    int passCount = 0;
//                    if (rulePassDetailListVo.getPassCount() != null) {
//                        passCount = rulePassDetailListVo.getPassCount();
//                    }
//                    rulePassDetailListVo.setPassCount(passCount + 1);
//                }
//                if (Arrays.asList(1, 2, 3).contains(detailVo.getResultStatus())) {
//                    int count = 0;
//                    if (rulePassDetailListVo.getCount() != null) {
//                        count = rulePassDetailListVo.getCount();
//                    }
//                    rulePassDetailListVo.setCount(count + 1);
//                }
//            }
//
//        }
//        List<RulePassRateListVo> rulePassRateListVos = new ArrayList<>(rulePassDetailListVoMap.values());
//        rulePassRateListVos.forEach(vo -> {
//            if (vo.getCount() > 0) {
//                if(vo.getPassCount() == null){
//                    vo.setPassCount(0);
//                }
//                vo.setRulePassRate(Math.round(vo.getPassCount() * 1.0 / vo.getCount() * 10000) / 10000.0);
//            } else {
//                vo.setRulePassRate(0.0);
//            }
//        });
//        return rulePassRateListVos;
//    }

    @Override
    public List<RuleOverDetailVo> smartCheckRuleOverRate(AjTicketTask task) {
        List<String> hasCodeTicketNames = Arrays.asList("员工费用报销单", "原材料结算报账单", "业务费用报销单", "多部门业务费用报销单", "差旅报销单", "入账通知单", "保证金接收", "保证金支付");
        List<String> hasNoCodeTicketNames = Arrays.asList("还款单", "员工领款单", "库存非原料结算报账单", "运费结算报账单", "单个支付申请", "借款单", "客户支付业务申请", "预付款");
        List<String> allTicketNames = new ArrayList<>();
        allTicketNames.addAll(hasCodeTicketNames);
        allTicketNames.addAll(hasNoCodeTicketNames);
        List<AjTicketType> ajTicketTypes = ticketTypeMapper.selectTicketTypeList(new AjTicketType() {{
            setCode(task.getTicketType());
        }});
        List<AjAttachCateRuleset> ajBussinessGroups = attachCateRulesetMapper.selectAttachCateRulesetList(new AjAttachCateRuleset());
        List<RuleOverDetailVo> ruleOverDetailVos = new ArrayList<>();
        for (AjTicketType ajTicketType : ajTicketTypes) {
            if (!allTicketNames.contains(ajTicketType.getName())) {
                continue;
            }
            List<AjAttachCateBusiness> attachCateBusinesses = attachCateBusinessMapper.selectAttachCateBusinessList(new AjAttachCateBusiness() {{
                setTicketTypeCode(ajTicketType.getCode());
            }});
            List<String> businessCateList = attachCateBusinesses.stream().map(AjAttachCateBusiness::getSmallCode).collect(Collectors.toList());
            List<AjRule> ajRules = ruleMapper.selectByParams2(ajTicketType.getCode(), businessCateList, null, task.getStartApplyDate(), task.getEndApplyDate());
            for (AjAttachCateBusiness attachCateBusiness : attachCateBusinesses) {


                for(AjAttachCateRuleset bussinessGroup : ajBussinessGroups) {
                    RuleOverDetailVo detailVo = new RuleOverDetailVo();
                    detailVo.setTicketType(ajTicketType.getName());
                    detailVo.setBusinessCate(attachCateBusiness.getSmallName());
                    List<AjRule> ruleList = new ArrayList<>();
                    for (AjRule ajRule : ajRules) {
                        if (StringUtils.isNotEmpty(ajRule.getBusinessCate())) {
                            List<String> businessCates = Arrays.asList(ajRule.getBusinessCate().split(","));
                            if (businessCates.contains(attachCateBusiness.getSmallCode()) && bussinessGroup.getName().equals(ajRule.getRuleDetail().getRuleGroup())) {
                                ruleList.add(ajRule);
                            }
                        } else if (hasNoCodeTicketNames.contains(ajTicketType.getName())&& bussinessGroup.getName().equals(ajRule.getRuleDetail().getRuleGroup())) {
                            ruleList.add(ajRule);
                        }
                    }
                    detailVo.setIsOver(ruleList.size() > 0 ? "是" : "否");
                    detailVo.setRuleCount(ruleList.size());
                    detailVo.setRuleset(bussinessGroup.getName());
                    ruleOverDetailVos.add(detailVo);
                }
            }
        }

        return ruleOverDetailVos;
    }
}
